﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;

namespace WFTerminator
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private IList<SPWorkflow> _internalList;

        private void FindButton_Click(object sender, EventArgs e)
        {
            StatusLabel.Text = string.Empty;

            try
            {
                RefreshList();
            }
            finally
            {
                StatusLabel.Text = _internalList.Count.ToString() + " Instances found!";
            }
        }

        private void RefreshList()
        {
            SPUserToken token = SPUserToken.SystemAccount;

            // Find the user Token
            if (!string.IsNullOrEmpty(UserNameText.Text))
            {
                using (SPSite s = new SPSite(UrlText.Text, SPUserToken.SystemAccount))
                {
                    using (SPWeb w = s.OpenWeb())
                    {
                        token = w.AllUsers[UserNameText.Text].UserToken;
                    }
                }
            }

            // Impersonate using user token
            using (SPSite site = new SPSite(UrlText.Text, token))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    List.Items.Clear();
                    _internalList = new List<SPWorkflow>();

                    IEnumerable<SPWorkflow> list = web.Workflows.Cast<SPWorkflow>().ToList<SPWorkflow>();

                    if ((InternalStateList.SelectedIndex != 0) && (InternalStateList.SelectedIndex != InternalStateList.Items.Count - 1))
                        list = list.Where(w => w.InternalState.ToString().Contains(InternalStateList.SelectedItem.ToString()));

                    if (!string.IsNullOrEmpty(AuthorUserText.Text))
                        list = list.Where(w => w.AuthorUser.ToString().ToLower().Contains(AuthorUserText.Text.ToLower()));

                    foreach (SPWorkflow workflow in list)
                    {
                        List.Items.Add(workflow.InternalState.ToString() + " Workflow created by " + workflow.AuthorUser.LoginName + " on " + workflow.Created.ToLongTimeString());
                        _internalList.Add(workflow);
                    }
                }
            }
        }

        private void TerminateButton_Click(object sender, EventArgs e)
        {
            if (List.SelectedIndex >= 0)
            {
                if (MessageBox.Show("Are you sure to Terminate this Workflow?", "Confirm", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {
                    SPWorkflow workflow = _internalList[List.SelectedIndex];

                    SPWorkflowManager.CancelWorkflow(workflow);

                    RefreshList();

                    MessageBox.Show("Terminated!");
                }
            }
        }

        private void List_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (grid.Visible)
            {
                SPWorkflow workflow = _internalList[List.SelectedIndex];
                grid.SelectedObject = workflow;
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            RefreshInternalStates();
        }

        private void RefreshInternalStates()
        {
            InternalStateList.Items.Clear();
            InternalStateList.Items.Add("- Select Internal State -");
            Enum.GetValues(typeof(SPWorkflowState)).Cast<SPWorkflowState>().ToList().ForEach(w => InternalStateList.Items.Add(w.ToString()));

            InternalStateList.SelectedIndex = InternalStateList.Items.IndexOf("Running");
        }
    }
}
